package com.sunny.client.v1;

import com.sunny.client.discover.IServiceDiscovery;
import com.sunny.service.RpcRequest;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

/**
 * @author Sunny
 * @date 2020/2/6
 */
public class RpcNetProcessHandler {

    private RpcRequest rpcRequest;

    public RpcNetProcessHandler(RpcRequest rpcRequest) {
        this.rpcRequest = rpcRequest;
    }

    Object invoke(IServiceDiscovery serviceDiscovery) {
        NioEventLoopGroup group = new NioEventLoopGroup();

        final RpcClientHandler handler = new RpcClientHandler();
        try {
            Bootstrap client = new Bootstrap();
            client.group(group)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();

                            pipeline.addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));
                            pipeline.addLast(new ObjectEncoder());
                            pipeline.addLast(handler);
                        }
                    });


            String serviceName = rpcRequest.getClassName() + "-" + rpcRequest.getVersion();
            String address = serviceDiscovery.discover(serviceName);
            String[] addressArr = address.split(":");
            ChannelFuture future = client.connect(addressArr[0], Integer.parseInt(addressArr[1])).sync();
            future.channel().writeAndFlush(rpcRequest).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            group.shutdownGracefully();
        }
        return handler.getResult();
    }
}
